import socket
import threading


# 服务端接收请求方法封装
def server_request(new_socket, ip_port):
    print('新的socket：', new_socket)
    print('建立连接的IP和端口号为：', ip_port)
    # 循环接收客户端消息
    while True:
        # 接收客户端数据
        # 1024: 每次接收的最大字节数（当客户端断开时，接收到一个长度为0的数据）
        recv_message = new_socket.recv(1024)
        if recv_message:
            # 解码
            print('接收到的数据为：', recv_message.decode('gbk'))
            # 发送数据
            new_socket.send('问题正在处理中'.encode('gbk'))
        else:
            print(ip_port, ' 已断开连接')
            break
    # 关闭连接 通话结束
    new_socket.close()


if __name__ == '__main__':
    # ip类型（这里为ipv4）
    # 传输协议（这里是TCP）
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用，服务端程序退出立即释放端口
    # 参数1:表示当前套接字
    # 参数2:设置端口号复用选项
    # 参数3:设置端口号复用选项对应的值
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号，第一个参数是ip地址，由于可能存在多个网卡，这里不指定，表示本机所有ip(传入的是一个元组)
    server_socket.bind(('', 9090))
    # 设置监听 128表示等待建立连接的最大个数
    server_socket.listen(128)
    while True:
        # 等待于客户端建立连接
        # 返回一个元组（客户端的socket,客户端IP和端口号）
        # 每当客户端和服务端建立连接成功后会返回一个新的socket
        # server_socket只负责与客户端建立连接，接收和发送客户端数据使用新的socket
        new_socket, ip_port = server_socket.accept()

        # 创建新的线程来处理连接
        sub_thread = threading.Thread(target=server_request, args=(new_socket, ip_port))
        # 设置为守护进程
        sub_thread.daemon = True
        # 开启线程
        sub_thread.start()

    # 不再接收新的请求，但已建立的请求还能正常通信
    # server_socket.close()
